﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using Risesun.Extend;

namespace Risesun.Web
{
    public static class HttpExtend
    {
        public static Expression RequestExpress(this Expression request, string name, Type type)
        {
            if (type.IsSimpleType())
            {
                var call = Expression.Call(request,
                    typeof(HttpRequest).GetProperty("Item").GetGetMethod(), Expression.Constant(name));
                return call.Convert(type);
            }

            if (type.IsArray && type.GetElementType().IsSimpleType())
            {
                Expression call = Expression.Call(request,
                    typeof(HttpRequest).GetProperty("Item").GetGetMethod(), Expression.Constant(name));
                call = call.ConvertList(type.GetElementType());
                return Expression.Call(typeof(Enumerable), "ToArray", new[] { type.GetElementType() }, call);
            }

            if (type.IsGenericType)
            {
                var args = type.GetGenericArguments();
                if (args.Length > 1)
                {
                    return null;
                }
                var elementType = args.First();
                if (elementType.IsSimpleType())
                {
                    Expression call = Expression.Call(request,
                            typeof(HttpRequest).GetProperty("Item").GetGetMethod(), Expression.Constant(name));
                    call = call.ConvertList(elementType);
                    
                    if (type == typeof(IList<>).MakeGenericType(elementType))
                    {
                        call = Expression.Call(typeof(Enumerable), "ToList", new[] { elementType }, call);
                        return Expression.Convert(call, type);
                    }
                    else if(type == typeof(List<>).MakeGenericType(elementType))
                    {
                        call = Expression.Call(typeof(Enumerable), "ToList", new[] { elementType }, call);
                        return call;
                    }
                    else if(type == typeof(IEnumerable<>).MakeGenericType(elementType))
                    {
                        return call;
                    }

                    HttpContext.Current.Request.req
                }
            }

            //if (type.IsGenericType || type.IsArray)
            //{
            //    return null;
            //}

            return type.IsClass ? RequestSingleClass(request, name, type) : null;
        }

        public static Expression RequestSingleClass(this Expression request, string name, Type type)
        {
            var properties = type.GetProperties();

            var list = from property in properties
                       select
                           Expression.Bind(property,
                               RequestExpress(request, string.Format("{0}.{1}", name, property.Name), property.PropertyType));

            return Expression.MemberInit(Expression.New(type), list.Where(x => x != null));
        }


        public static Expression Request(this Expression context)
        {
            var request = Expression.Call(context, typeof(HttpContext).GetProperty("Request").GetGetMethod());
            return request;
        }
    }
}